/*
 * CCVisu is a tool for visual graph clustering
 * and general force-directed graph layout.
 * This file is part of CCVisu.
 *
 * Copyright (C) 2005-2012  Dirk Beyer
 *
 * CCVisu is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * CCVisu is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with CCVisu; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Please find the GNU Lesser General Public License in file
 * license_lgpl.txt or http://www.gnu.org/licenses/lgpl.txt
 *
 * Dirk Beyer    (firstname.lastname@uni-passau.de)
 * University of Passau, Bavaria, Germany
 */
package org.sosy_lab.ccvisu.ui.controlpanel;

import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.sosy_lab.ccvisu.Options;
import org.sosy_lab.ccvisu.Options.OptionsEnum;
import org.sosy_lab.ccvisu.measuring.calldep.DependencyCalculator;
import org.sosy_lab.ccvisu.measuring.calldep.DistanceVertexContainer;
import org.sosy_lab.ccvisu.measuring.calldep.OutdegreeVertexContainer;
import org.sosy_lab.ccvisu.measuring.calldep.colors.ColorProvider;
import org.sosy_lab.util.interfaces.WorkerManager;

public class ToolPanelMeasurer extends ControlPanel {
  private static final long serialVersionUID = -7114139321544094720L;

  private Options            options;
  private WorkerManager      workerManager;

  private JButton            startAnalysisButton = new JButton("Run dependency analyzer");

  // generic since Java 7; we require Java 6; see svn r825 for comparison
  private JComboBox<String>  algorithmComboBox   = new JComboBox<>();

  private JComboBox<String>  coloringComboBox    = new JComboBox<>();

  private SpinnerNumberModel labelSpinnerModel;

  public ToolPanelMeasurer(Options options, WorkerManager worker) {
    this.options = options;
    this.workerManager = worker;

    initComponents();
  }

  @Override
  public void loadOptions() {
    // nothing to load right now
  }

  @Override
  public void applyOptions() {
    options.getOption(OptionsEnum.dependencyAlgorithm).set((String) algorithmComboBox.getSelectedItem());
    options.getOption(OptionsEnum.dependencyColoring).set((String) coloringComboBox.getSelectedItem());
    options.getOption(OptionsEnum.dependencyShowLabels).set(labelSpinnerModel.getNumber().intValue());
  }

  private void initComponents() {
    JPanel optionsPanel = new JPanel();

    String[] algorithms = { DistanceVertexContainer.ALGORITHM_NAME,
                            OutdegreeVertexContainer.ALGORITHM_NAME };

    algorithmComboBox.setModel(new DefaultComboBoxModel<String>(algorithms));
    algorithmComboBox.setSelectedItem(OptionsEnum.dependencyAlgorithm.getDefault());

    coloringComboBox.setModel(new DefaultComboBoxModel<String>(ColorProvider.getInstance().getColorOptions()));
    coloringComboBox.setSelectedItem(ColorProvider.getInstance().getDefaultColorOption());

    int labelValue = options.getOption(OptionsEnum.dependencyShowLabels).getInt();
    labelSpinnerModel = new SpinnerNumberModel(labelValue, 0, 999, 1);

    JSpinner autoShowLabelBox = new JSpinner(labelSpinnerModel);

    optionsPanel.setLayout(new GridBagLayout());
    addOptionControls(optionsPanel, "Measure:", algorithmComboBox);
    algorithmComboBox.setToolTipText(String.format("<html>Set the measure to use for coloring:<ul><li>%s</li><li>%s</li></ul></html>",
        DistanceVertexContainer.DESCRIPTION,
        OutdegreeVertexContainer.DESCRIPTION));

    addOptionControls(optionsPanel, "Coloring scheme:", coloringComboBox);
    coloringComboBox.setToolTipText("<html>Set the coloring scheme. Red indicates a higher measurement result.</html>");

    addOptionControls(optionsPanel, "Automatically shown number of labels:", autoShowLabelBox);
    autoShowLabelBox.setToolTipText("The number of nodes for which labels that are to be shown," +
    		" starting with the node with the highest measurement result.");

    JPanel controlPanel = new JPanel();
    controlPanel.add(startAnalysisButton);

    startAnalysisButton.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        workerManager.addAndRunTask(new DependencyCalculator(options.graph, options),
            "Dependency Analysis");
      }
    });

    setLayout(new BorderLayout());
    add(optionsPanel, BorderLayout.NORTH);
    add(controlPanel, BorderLayout.SOUTH);

    ChangeListener applyOnChange = new ChangeListener() {
      @Override
      public void stateChanged(ChangeEvent event) {
        applyOptions();
      }
    };

    ActionListener applyOnAction = new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent event) {
        applyOptions();
      }
    };

    algorithmComboBox.addActionListener(applyOnAction);
    coloringComboBox.addActionListener(applyOnAction);
    autoShowLabelBox.addChangeListener(applyOnChange);

    setMnemonics();
  }

  private void setMnemonics() {
    startAnalysisButton.setMnemonic('R');
  }
}
